package com.tlgen.orm.components.autoFill;

import com.tlgen.orm.enums.FillType;
import com.tlgen.orm.service.impl.EntityImpl;

import java.util.function.BiConsumer;
import java.util.function.Function;

/**
 * 实体生命周期执行器
 */
public class LifecycleExecutor {

    /**
     * 执行带生命周期的操作
     *
     * @param entity 实体对象
     * @param operationType 操作类型
     * @param beforeAction 前置操作 (实体, 实现类) -> void
     * @param dbAction 数据库操作 (实体) -> 操作结果
     * @param afterAction 后置操作 (实体, 实现类, 操作结果) -> void
     * @param <T> 实体类型
     * @param <R> 数据库操作结果类型
     */
    public static <T, R> void execute(
            Object entity,
            FillType operationType,
            BiConsumer<T, EntityImpl<T>> beforeAction,
            Function<T, R> dbAction,
            TriConsumer<T, EntityImpl<T>, R> afterAction
    ) {
        try {
            // 1. 设置操作上下文
            OperationContext.pushOperationType(operationType);

            // 2. 获取实体实现
            @SuppressWarnings("unchecked")
            EntityImpl<T> entityImpl = (EntityImpl<T>) EntityImplHandlerLoader.getHandler(entity.getClass());

            // 3. 执行前置操作
            beforeAction.accept((T) entity, entityImpl);

            // 4. 执行自动填充
            executeAutoFill(entity, operationType);

            // 5. 执行数据库操作
            R result = dbAction.apply((T) entity);

            // 6. 执行后置操作
            afterAction.accept((T) entity, entityImpl, result);
        } finally {
            // 7. 清除操作上下文
            OperationContext.clear();
        }
    }

    /**
     * 执行自动填充
     * @param entity 实体对象
     * @param operationType 操作类型
     */
    private static void executeAutoFill(Object entity, FillType operationType) {
        AutoFillHandler handler = AutoFillHandlerLoader.getHandler();
        if (operationType == FillType.INSERT) {
            handler.save(entity);
        } else if (operationType == FillType.UPDATE) {
            handler.update(entity);
        }
    }

    /**
     * 三参数消费者接口
     * @param <T> 第一个参数类型
     * @param <U> 第二个参数类型
     * @param <V> 第三个参数类型
     */
    @FunctionalInterface
    public interface TriConsumer<T, U, V> {
        void accept(T t, U u, V v);
    }

}